package com.moji.config;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.moji.util.JwtTokenUtil;
import com.moji.util.ResultCode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Configuration
public class TokenFilter implements Filter {

    private static Logger logger = LoggerFactory.getLogger(TokenFilter.class);


    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        //设置编码格式
        httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
        //获取请求的url
        String url = httpServletRequest.getRequestURI();
        logger.info("当前登录账号url——获取=================="+url);
        //需要过滤的url
        Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
                Arrays.asList("/swagger-ui.html",
                              "/v2/api-docs",
                              "/doc.html",
                              "/api/login",
                              "/login",
                              "/swagger-resources/configuration/ui",
                              "/api/logout",
                              "/swagger-resources",
                              "/api/ccpBasicInfoCfg/getCcpBasicInfo",
                              "/api/getUserCode",
                              "/api/getUserCode",
                              "/api/MjUploadFiles/picture"
                              )));
        //获取token令牌
        String token = this.resolveToken(httpServletRequest);
        //预加载不校验token
        if ("OPTIONS".equals(httpServletRequest.getMethod())) {
            httpServletResponse.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {
            if (ALLOWED_PATHS.contains(url) || url.contains("js") || url.contains("css") || url.contains("rest")) {
                filterChain.doFilter(servletRequest, servletResponse);
            }else {
                if (url.contains("web") && !url.contains("auth")) {
                    filterChain.doFilter(servletRequest, servletResponse);
                } else {
                    //判断token是否为空
                    if (StringUtils.isEmpty(token)) {
                        int code = new Long(ResultCode.TOKEN_IS_NULL.getCode()).intValue();
                        httpServletResponse.sendError(code, ResultCode.TOKEN_IS_NULL.getMsg());
                        return;
                    }

                    //判断token是否过期
//                if(!redisTemplate.hasKey(token)){
//                    int code = new Long(ResultCode.TOKEN_IS_EXPIRE.getCode()).intValue();
//                    httpServletResponse.sendError(code,ResultCode.TOKEN_IS_EXPIRE.getMsg());
//                    return;
//                } else{
//                    //放入redis缓存
//                    //redisTemplate.opsForValue().set(token,token, Integer.valueOf(CcpEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//                    //redisTemplate.expire(token, Integer.valueOf(CcpEnumConfig.CCP_SYSTEM_TOKEN_TIME.getCode()), TimeUnit.MINUTES);
//                }
                    //解析token
                    Map<String, Claim> userData = null;
                    String userName = "";
                    try {
                        userData = jwtTokenUtil.verifyToken(token);
                        userName = userData.get("loginId").asString();
                        Date date = userData.get("exp").asDate();
                        logger.info("token自身过期时间==================" + date);
                    } catch (TokenExpiredException tokenExpiredException) {
                        int code = new Long(ResultCode.TOKEN_IS_EXPIRE.getCode()).intValue();
                        httpServletResponse.sendError(code, ResultCode.TOKEN_IS_EXPIRE.getMsg());
                        return;
                    } catch (Exception e) {
                        logger.error(e.getMessage());
                        logger.error("token解码异常");
                        //解码异常则抛出异常
                        int code = new Long(ResultCode.TOKEN_IS_ERROR.getCode()).intValue();
                        httpServletResponse.sendError(code, ResultCode.TOKEN_IS_ERROR.getMsg());
                        return;
                    }
                    logger.info("当前登录账号==================" + userName);
                    filterChain.doFilter(servletRequest, servletResponse);
                }
            }
        }

    }

    /**
     * 获取Token
     *
     * @param request /
     * @return /
     */
    private String resolveToken(HttpServletRequest request) {
        return request.getHeader("Authorization");
    }
}
